package top.lyjwn.todo.common.config;

import com.alibaba.fastjson2.JSONObject;
import io.lettuce.core.resource.DefaultClientResources;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import top.lyjwn.todo.common.redis.FastJson2JsonRedisSerializer;

import java.time.Duration;

@ConditionalOnClass({RedisTemplate.class})
@ConditionalOnProperty(
        prefix = "lyjwn",
        value = {"enabled"},
        matchIfMissing = true
)
@Configuration
public class RedisConfig  implements EnvironmentAware {


    protected Environment environment;

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }


/*
//    @Value("${top.lyjwn.todo.common.redis.host}")
    private String host;

//    @Value("${top.lyjwn.todo.common.redis.port}")
    private int port;

//    @Value("${top.lyjwn.todo.common.redis.password}")
    private String password;

//    @Value("${top.lyjwn.todo.common.redis.max-active}")
    private int maxActive;

//    @Value("${top.lyjwn.todo.common.redis.max-idle}")
    private int maxIdle;

//    @Value("${top.lyjwn.todo.common.redis.min-idle}")
    private int minIdle;

//    @Value("${top.lyjwn.todo.common.redis.max-wait}")
    private int maxWait;
*/



    /**
     * 创建连接池
     *
     * @param index
     * @return
     */
    public LettuceConnectionFactory getLettuceConnectionFactory(int index) {
        String host = environment.getProperty("lyjwn.redis.host","127.0.0.1");
        String port_str = environment.getProperty("lyjwn.redis.port","6379");
        int port = port_str!=null?Integer.parseInt(port_str):null;
        String password = environment.getProperty("lyjwn.redis.password");
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        String maxActive_str = environment.getProperty("lyjwn.redis.maxActive");
        if (maxActive_str!=null)
        {
            genericObjectPoolConfig.setMaxIdle(Integer.parseInt(maxActive_str));
        }

        String maxIdle_str = environment.getProperty("lyjwn.redis.maxIdle");
        if (maxIdle_str!=null)
        {
            genericObjectPoolConfig.setMinIdle(Integer.parseInt(maxIdle_str));
        }
        String minIdle_str = environment.getProperty("lyjwn.redis.minIdle");
        if (minIdle_str!=null)
        {
            genericObjectPoolConfig.setMinIdle(Integer.parseInt(minIdle_str));
        }
        String maxWait_str = environment.getProperty("lyjwn.redis.maxWait");
        if (maxWait_str!=null)
        {
            int maxWait = Integer.parseInt(maxWait_str);
            genericObjectPoolConfig.setMaxWait(Duration.ofMillis(maxWait));
        }
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setDatabase(index);
        redisStandaloneConfiguration.setHostName(host);
        redisStandaloneConfiguration.setPort(port);
        redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
        LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                .poolConfig(genericObjectPoolConfig)
                .clientResources(DefaultClientResources.create())
                .build();

        LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);
        // 重新初始化工厂
        factory.afterPropertiesSet();
        return factory;
    }

    /**
     * 获取redis模板实例
     *
     * @param index
     * @return
     */
    public <T> RedisTemplate<String, T> getRedisTemplate(Class<T> tClass,int index) {
        RedisTemplate<String, T> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(getLettuceConnectionFactory(index));
        redisTemplate.setKeySerializer(new StringRedisSerializer());
//        GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
        FastJson2JsonRedisSerializer<T> fastJsonRedisSerializer = new FastJson2JsonRedisSerializer<T>();
        fastJsonRedisSerializer.settClass(tClass);
        redisTemplate.setValueSerializer(fastJsonRedisSerializer);
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
        //序列化
//        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
//        ObjectMapper mapper = new ObjectMapper();
//        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//        serializer.setObjectMapper(mapper);
//
//        template.setKeySerializer(new StringRedisSerializer());
//        template.setValueSerializer(serializer);
//        template.setHashKeySerializer(new StringRedisSerializer());
//        template.setHashValueSerializer(serializer);
//        template.afterPropertiesSet();
        return redisTemplate;
    }







}
